/*****************************************************************************
* Project:
* All project
* Copyright(C) 2020-2021 Shenju Co.Ltd, All rights reserved.
* Description:
* All code is genrated by yangyang
* Author:
* yangyang
****************************************************************************/
#include "oal_type.h"

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <String.h>
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Memory calc
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define MAX_POOL_SIZE	2048
static unsigned int count_malloc = 0;
static unsigned int nMaxMemoryAllocated = 0;
static unsigned int nTotalMemoryAllocated = 0;
#define DISPLAY_LARGE_MEM_DUMP_SIZE 0
typedef struct _mem_pool_ {
	void *p;
	int size;
	int line;
	char file[MAXPATH];
}mem_pool_t;
mem_pool_t mem_pool[MAX_POOL_SIZE];

void OAL_InitMemoryUsage()
{
	count_malloc = 0;
	nMaxMemoryAllocated = 0;
	nTotalMemoryAllocated = 0;
	memset(mem_pool, 0, sizeof(mem_pool_t)*MAX_POOL_SIZE);
}
void OAL_DumpMemoryUsage(unsigned int overSize2display)
{
	int i;
	printf("\tSize\t\tLine\tFile\n");
	for (i = 0; i < MAX_POOL_SIZE; i++) {
		//	printf("hehe");
		if (mem_pool[i].size>(int)overSize2display) {
			printf("\t%d\t\t%d\t%s\n", mem_pool[i].size, mem_pool[i].line, mem_pool[i].file);
		}
	}

	printf("Maxinum memory alloced once: %d bytes\n", nMaxMemoryAllocated);
	printf("Count of total memory allocated now: %d times\n", count_malloc);
	printf("Total memory allocated now: %d\n", nTotalMemoryAllocated);
}

static int OAL_AddAllocItem(void *ptr, int size, char *file, int line)
{
	int i;
	nTotalMemoryAllocated += size;
	count_malloc++;
	if (size > (int)nMaxMemoryAllocated)
		nMaxMemoryAllocated = size;

	for (i = 0; i<MAX_POOL_SIZE; i++) {
		if (mem_pool[i].size == 0) {
			mem_pool[i].p = ptr;
			mem_pool[i].size = size;
			mem_pool[i].line = line;
			strcpy_s(mem_pool[i].file, MAXPATH, file);
			break;
		}
	}
	if (i == MAX_POOL_SIZE)
		printf("memory pool not enough\n");
	return 0;
}
static int OAL_DelAllocItem(void *ptr, char *file, int line)
{
	if (ptr != 0)
	{
		int i;
		int deleted = 0;
		unsigned int thisMemorySize = 0;
		for (i = 0; i < MAX_POOL_SIZE; i++) {
			if (mem_pool[i].size>0 && mem_pool[i].p == ptr) {
				thisMemorySize = mem_pool[i].size;
				nTotalMemoryAllocated -= mem_pool[i].size;
				mem_pool[i].size = 0;
				mem_pool[i].p = 0;
				deleted = i;
				break;
			}
		}
		for (i = deleted + 1; i < MAX_POOL_SIZE; i++) {
			if (mem_pool[i].size > 0) {
				mem_pool[i - 1].size = mem_pool[i].size;
				mem_pool[i - 1].p = mem_pool[i].p;
				mem_pool[i - 1].line = mem_pool[i].line;
				strcpy_s(mem_pool[i - 1].file, MAXPATH, mem_pool[i].file);
				memset(&mem_pool[i], 0, sizeof(mem_pool_t));
			}
			else
				break;
		}
		if (thisMemorySize == 0)
		{
			// ?? not in calc ???
			printf("Lost calc this OAL_free item: file: %s, line: %d\n", file, line);
		}
		else
			count_malloc--;
	}

	return 0;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Memory  
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define MAX_HEAP_SIZE	2*1024*1024

unsigned int OAL_MemFreeSize()
{
	return MAX_HEAP_SIZE - nTotalMemoryAllocated;
}

void* OAL_malloc1(uint32_t size)
{
	return  malloc(size);
}
void* OAL_malloc2(uint32_t size, char *file, int line)
{
	void *ret;
	if (size + nTotalMemoryAllocated > MAX_HEAP_SIZE)
	{
		printf("[win32mem]: !!!xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxoal_malloc %d failed. %s:%d.\n", size, file, line);
		return 0;
	}
		
	ret = malloc(size);
	if (ret)
		OAL_AddAllocItem(ret, size, file, line);
	else
		OAL_DumpMemoryUsage(0);

	return ret;
}
void* OAL_calloc1(uint32_t count, uint32_t size)
{
	return calloc(count, size);
}
void* OAL_calloc2( uint32_t count, uint32_t size, char *file, int line)
{
	void *ret;
	if (size*count + nTotalMemoryAllocated > MAX_HEAP_SIZE)
	{
		printf("[win32mem]: !!!xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxoal_calloc %d failed. %s:%d.\n", size, file, line);
		return 0;
	}
	ret = calloc(count, size);
	if (ret)
		OAL_AddAllocItem(ret, size*count, file, line);
	else
		OAL_DumpMemoryUsage(0);
	return ret;
}
void* OAL_realloc1(void *memory, uint32_t size)
{
	return realloc(memory, size);
}
void* OAL_realloc2( void *memory, uint32_t size, char *file, int line)
{
	void *ret;
	if (size + nTotalMemoryAllocated > MAX_HEAP_SIZE)
	{
		printf("[win32mem]: !!!xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxoal_realloc %d failed. %s:%d.\n", size, file, line);
		return 0;
	}
	ret = realloc(memory, size);
	if (ret)
	{
		OAL_DelAllocItem(memory, file, line);
		OAL_AddAllocItem(ret, size, file, line);
	}

	return ret;
}
void OAL_free1(void*memory)
{
	free(memory);
}
void OAL_free2(void *memory, char *file, int line)
{
	if (memory == 0)
		return;
	free( memory );
	OAL_DelAllocItem(memory, file, line);
}

void *OAL_memcpy( void *dst, const void *src, uint32_t size)
{
	return memcpy( dst, src, size );
}

void* OAL_memset( void *dst, int c, uint32_t size)
{
	return memset(dst, c, size);
}
